package com.zxhhyj.storm.common

import com.zxhhyj.storm.schema.Table

object SQL {
    fun createTableStr(table: Table<*>, ifNotExists: Boolean = false): String {
        val columnArgs = table.columns.map { column ->
            val modifier = StringBuilder("${column.fieldName} ${column.dataType}")
            if (!column.isNull) {
                modifier.append(" NOT NULL")
            }
            if (column.isUnique) {
                modifier.append(" UNIQUE")
            }
            if (column.isPrimaryKey) {
                modifier.append(" PRIMARY KEY")
            }
            if (column.isAutoincrement) {
                modifier.append(" AUTOINCREMENT")
            }
            column.defaultProvider?.let {
                modifier.append(" DEFAULT '${it.invoke()}'")
            }
            modifier
        }
        val sql =
            "CREATE TABLE ${if (ifNotExists) "IF NOT EXISTS ${table.tableName}" else table.tableName} (${columnArgs.joinToString { it }});".trimIndent()
        return sql
    }

    fun insertIntoStr(table: Table<*>, values: Map<String, *>): String {
        return "INSERT INTO ${table.tableName} (${values.keys.joinToString { it }}) VALUES (${values.values.joinToString { "\'${it}\'" }});"
    }

    fun batchInsertIntoStr(table: Table<*>, rows: List<Map<String, *>>): String {
        val columns = rows.first().keys.toList()
        val columnNames = columns.joinToString(", ")

        val valueGroups = rows.map { row ->
            columns.joinToString(", ") { column ->
                when (val value = row[column]) {
                    is String -> {
                        "'${value.replace("'", "''")}'"
                    }
                    is Boolean -> {
                        if (value) "1" else "0"
                    }
                    null -> {
                        "NULL"
                    }
                    else -> {
                        value.toString()
                    }
                }
            }
        }

        val valuesSql = valueGroups.joinToString(separator = ",") {
            "(${it})"
        }

        return "INSERT INTO ${table.tableName} ($columnNames) VALUES $valuesSql;".trimIndent()
    }
}